package notification

import (
	"fmt"
	"sync"
	"time"
)

// MessageType 消息类型
type MessageType string

const (
	MessageTypeProcessAlert    MessageType = "process_alert"
	MessageTypeProcessRestart  MessageType = "process_restart"
	MessageTypeProcessRecovery MessageType = "process_recovery"
	MessageTypeSystemAlert     MessageType = "system_alert"
	MessageTypeTest            MessageType = "test"
)

// AggregatedMessage 聚合消息
type AggregatedMessage struct {
	Type        MessageType `json:"type"`
	ServerID    string      `json:"server_id"`
	ProcessName string      `json:"process_name,omitempty"`
	Count       int         `json:"count"`
	FirstTime   time.Time   `json:"first_time"`
	LastTime    time.Time   `json:"last_time"`
	Messages    []string    `json:"messages"`
	Status      string      `json:"status"`
}

// MessageAggregator 消息聚合器
type MessageAggregator struct {
	mu                sync.RWMutex
	messages          map[string]*AggregatedMessage
	aggregateDuration time.Duration
	maxMessages       int
}

// NewMessageAggregator 创建消息聚合器
func NewMessageAggregator(aggregateDuration time.Duration, maxMessages int) *MessageAggregator {
	ma := &MessageAggregator{
		messages:          make(map[string]*AggregatedMessage),
		aggregateDuration: aggregateDuration,
		maxMessages:       maxMessages,
	}

	// 启动清理协程
	go ma.cleanup()

	return ma
}

// AddMessage 添加消息
func (ma *MessageAggregator) AddMessage(msgType MessageType, serverID, processName, message, status string) *AggregatedMessage {
	ma.mu.Lock()
	defer ma.mu.Unlock()

	key := ma.getKey(msgType, serverID, processName)
	now := time.Now()

	if existing, exists := ma.messages[key]; exists {
		// 更新现有消息
		existing.Count++
		existing.LastTime = now
		existing.Status = status

		// 添加新消息到列表
		if len(existing.Messages) < ma.maxMessages {
			existing.Messages = append(existing.Messages, message)
		}

		return existing
	} else {
		// 创建新消息
		newMsg := &AggregatedMessage{
			Type:        msgType,
			ServerID:    serverID,
			ProcessName: processName,
			Count:       1,
			FirstTime:   now,
			LastTime:    now,
			Messages:    []string{message},
			Status:      status,
		}

		ma.messages[key] = newMsg
		return newMsg
	}
}

// GetMessage 获取聚合消息
func (ma *MessageAggregator) GetMessage(msgType MessageType, serverID, processName string) *AggregatedMessage {
	ma.mu.RLock()
	defer ma.mu.RUnlock()

	key := ma.getKey(msgType, serverID, processName)
	return ma.messages[key]
}

// RemoveMessage 移除消息
func (ma *MessageAggregator) RemoveMessage(msgType MessageType, serverID, processName string) {
	ma.mu.Lock()
	defer ma.mu.Unlock()

	key := ma.getKey(msgType, serverID, processName)
	delete(ma.messages, key)
}

// GetAllMessages 获取所有消息
func (ma *MessageAggregator) GetAllMessages() map[string]*AggregatedMessage {
	ma.mu.RLock()
	defer ma.mu.RUnlock()

	result := make(map[string]*AggregatedMessage)
	for k, v := range ma.messages {
		result[k] = v
	}
	return result
}

// getKey 生成消息键
func (ma *MessageAggregator) getKey(msgType MessageType, serverID, processName string) string {
	return fmt.Sprintf("%s:%s:%s", msgType, serverID, processName)
}

// cleanup 清理过期消息
func (ma *MessageAggregator) cleanup() {
	ticker := time.NewTicker(ma.aggregateDuration)
	defer ticker.Stop()

	for range ticker.C {
		ma.mu.Lock()
		now := time.Now()

		for key, msg := range ma.messages {
			if now.Sub(msg.LastTime) > ma.aggregateDuration {
				delete(ma.messages, key)
			}
		}

		ma.mu.Unlock()
	}
}

// GetCardMessage 获取卡片消息
func (msg *AggregatedMessage) GetCardMessage() *FeishuCardMessage {
	card := NewCardMessage()

	switch msg.Type {
	case MessageTypeProcessAlert:
		card.SetHeader("🚨 进程监控告警", "red")
		card.AddMarkdown(fmt.Sprintf("**服务器**: %s", msg.ServerID))
		card.AddMarkdown(fmt.Sprintf("**进程名称**: %s", msg.ProcessName))
		card.AddMarkdown(fmt.Sprintf("**状态**: %s", msg.Status))
		card.AddMarkdown(fmt.Sprintf("**告警次数**: %d", msg.Count))
		card.AddMarkdown(fmt.Sprintf("**首次告警**: %s", msg.FirstTime.Format("2006-01-02 15:04:05")))
		card.AddMarkdown(fmt.Sprintf("**最后告警**: %s", msg.LastTime.Format("2006-01-02 15:04:05")))

	case MessageTypeProcessRestart:
		card.SetHeader("🔄 进程重启告警", "orange")
		card.AddMarkdown(fmt.Sprintf("**服务器**: %s", msg.ServerID))
		card.AddMarkdown(fmt.Sprintf("**进程名称**: %s", msg.ProcessName))

		// 只有当重启次数大于0时才显示重启统计信息
		if msg.Count > 0 {
			card.AddMarkdown(fmt.Sprintf("**重启次数**: %d", msg.Count))
			card.AddMarkdown(fmt.Sprintf("**首次重启**: %s", msg.FirstTime.Format("2006-01-02 15:04:05")))
			card.AddMarkdown(fmt.Sprintf("**最后重启**: %s", msg.LastTime.Format("2006-01-02 15:04:05")))
		}

	case MessageTypeProcessRecovery:
		card.SetHeader("✅ 进程恢复通知", "green")
		card.AddMarkdown(fmt.Sprintf("**服务器**: %s", msg.ServerID))
		card.AddMarkdown(fmt.Sprintf("**进程名称**: %s", msg.ProcessName))
		card.AddMarkdown(fmt.Sprintf("**状态**: 已恢复"))
		card.AddMarkdown(fmt.Sprintf("**恢复时间**: %s", msg.LastTime.Format("2006-01-02 15:04:05")))

	case MessageTypeSystemAlert:
		card.SetHeader("⚠️ 系统告警", "red")
		card.AddMarkdown(fmt.Sprintf("**服务器**: %s", msg.ServerID))
		card.AddMarkdown(fmt.Sprintf("**告警类型**: %s", msg.ProcessName))
		card.AddMarkdown(fmt.Sprintf("**告警次数**: %d", msg.Count))
		card.AddMarkdown(fmt.Sprintf("**首次告警**: %s", msg.FirstTime.Format("2006-01-02 15:04:05")))
		card.AddMarkdown(fmt.Sprintf("**最后告警**: %s", msg.LastTime.Format("2006-01-02 15:04:05")))

	case MessageTypeTest:
		card.SetHeader("🧪 飞书通知测试", "blue")
		card.AddMarkdown(fmt.Sprintf("**服务器**: %s", msg.ServerID))
		card.AddMarkdown(fmt.Sprintf("**测试时间**: %s", msg.LastTime.Format("2006-01-02 15:04:05")))
		card.AddMarkdown(fmt.Sprintf("**状态**: 测试成功"))
	}

	// 添加分割线
	card.AddDiv()

	// 添加详情
	if len(msg.Messages) > 0 {
		card.AddMarkdown(fmt.Sprintf("**详情**: %s", msg.Messages[len(msg.Messages)-1]))
	}

	// 添加备注
	if msg.Count > 1 {
		card.AddNote(fmt.Sprintf("此消息已聚合 %d 次告警，请及时处理", msg.Count))
	} else {
		card.AddNote("请及时处理异常，避免影响业务正常运行")
	}

	return card
}
